#!/usr/bin/python3
# -*- coding: utf-8 -*-

from logging import getLogger
from flask import render_template, Blueprint
from sqlalchemy import or_
from sqlalchemy.orm import joinedload

from ..core.validators import reject_if_null, reject_if_blank
from ..core.entities import Node
from ..core.metadata import find_credential
from ..models import db, NodePO

bp = Blueprint('nodes', __name__)

_LOGGER = getLogger(__name__)


@bp.route('/')
@bp.route('/index')
@bp.route('/index(<search_key>)')
def index(
        search_key: str = None
):
    search_key = search_key.strip() if search_key else ''
    return render_template('nodes/index.html',
                           nodes=tuple(to_node(n) for n in _query(search_key).options(joinedload('props')).all()),
                           search_key=search_key, path_to=('nodes', 'index',))


def _query(
        key: str
):
    reject_if_null(key)

    q = NodePO.query
    if key:
        q = q.filter(or_(NodePO.name.like(key + '%'), NodePO.description.like(key + '%')))

    return q


def to_node(
        po: NodePO
) -> (Node, None):
    if not po:
        return None

    prop_dict = po.prop_dict
    if prop_dict:
        credential_keys = set(key for key in prop_dict if key.endswith('-credential'))
        for ck in credential_keys:
            cn = prop_dict.get(ck, '')
            credential = find_credential(cn)
            if credential:
                prop_dict[ck] = credential
            else:
                del prop_dict[ck]
                _LOGGER.warning('Cannot find credential: %s', cn)

    return Node(
        name=po.name,
        description=po.description,
        hostname=po.hostname,
        bundle=po.bundle,
        enabled=po.enabled,
        props=prop_dict
    )
